package com.ruoyi.web.controller.api;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.alibaba.fastjson2.JSON;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.user.vo.LoginVo;
import com.ruoyi.web.domain.user.vo.RegisterVo;
import com.ruoyi.web.domain.user.vo.SubscribeVo;
import com.ruoyi.web.entity.user.response.UserCenterResponse;
import com.ruoyi.web.mapper.ApiUserMapper;
import com.ruoyi.web.service.ApiUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;

/**
 * 用户信息
 * 
 * @author ruoyi
 */
@Api(tags = "微信模块")
@RestController
@RequestMapping("/api/wechat")
public class WeChatController extends BaseController
{

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private WxMpService wxMpService;

    @ApiOperation(value = "登录测试")
    @ApiOperationSupport(author = "有为", order = 1)
    @RequestMapping(value = "/sign", method = {RequestMethod.GET, RequestMethod.POST})
    public String login(@RequestParam(required = false) String echostr,
                            @RequestParam(required = false) String signature,
                            @RequestParam(required = false) String stimestamp,
                            @RequestParam(required = false) String nonce) {

        System.out.println("sign");

        return echostr;
    }

    @ApiOperation(value = "构建链接")
    @ApiOperationSupport(author = "有为", order = 1)
    @GetMapping("/authorize")
    public String auth(@RequestParam("returnUrl") String returnUrl) throws WxErrorException {

        System.out.println("code: " + returnUrl);

        String url = "http://8wgnad.natappfree.cc/api/wechat/userInfo";

        // 这个回调地址是不会变动的
        // https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb569c8e86048b488&redirect_uri=http%3A%2F%2F8wgnad.natappfree.cc%2Fapi%2Fwechat%2FuserInfo&response_type=code&scope=snsapi_base&state=login&connect_redirect=1#wechat_redirect
        String authUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(
                url, WxConsts.OAuth2Scope.SNSAPI_BASE, "login"
        );
        System.out.println("url:" + authUrl);

        return authUrl;
    }

    @ApiOperation(value = "获取auth")
    @ApiOperationSupport(author = "有为", order = 1)
    @GetMapping("/userInfo")
    public String auth(@RequestParam("code") String code,
                       @RequestParam("state") String returnUrl) throws WxErrorException {

        System.out.println("code: " + code);

        WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);

        System.out.println("token:" + accessToken);

        // 获取用户基本信息, 测试的没权限稍后再试试.
//        WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(accessToken, null);
//        System.out.println("wxMpUser:" + wxMpUser);

        return "redirect:"+returnUrl + "?opendid=" + accessToken.getOpenId();
    }


    /**
     * 登陆接口
     */
    @GetMapping("/login")
    @ApiOperation(value = "小程序登录")
    public String login(String code) {
        if (StringUtils.isBlank(code)) {
            return "empty jscode";
        }

//        if (!wxMaService.switchover(appid)) {
//            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
//        }

        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            logger.info(JSON.toJSONString(session));
            //TODO 可以增加自己的逻辑，关联业务相关数据
            return JSON.toJSONString(session);
        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
            return e.toString();
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @GetMapping("/info")
    @ApiOperation(value = "小程序获取用户信息接口")
    public String info(String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
//        if (!wxMaService.switchover(appid)) {
//            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
//        }

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return JSON.toJSONString(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/phone")
    @ApiOperation(value = "获取用户绑定手机号信息")
    public String phone(String sessionKey, String signature,
                        String rawData, String encryptedData, String iv) {
//        if (!wxMaService.switchover(appid)) {
//            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
//        }

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return JSON.toJSONString(phoneNoInfo);
    }

}
